﻿/*----------------------------------------------------------------
//  <copyright file="HubEventDataBase.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2023-01-05 17:54</last-date>
//----------------------------------------------------------------*/

namespace MicroCloud.AspNetCore.SignalR.Events
{
    #region "集线器事件数据基类"
    /// <summary>
    /// 集线器事件数据基类
    /// </summary>
    public abstract class HubEventDataBase : EventDataBase
    {
        #region "属性"
        #region "获取 中心内部调用"
        /// <summary>
        /// 获取 中心内部调用
        /// （从 类外部调用客户端方法 Hub 时，没有与调用关联的调用方。 因此，无法访问 ConnectionId 、 Caller 和 Others 属性。）
        /// </summary>
        public bool Internal { get; }
        #endregion

        #region "获取 调用方客户端对象"
        /// <summary>
        /// 获取 调用方客户端对象
        /// </summary>
        public IHubClients Clients { get; }
        #endregion

        #region "获取 中心调用方客户端对象"
        /// <summary>
        /// 获取 中心调用方客户端对象
        /// </summary>
        public IHubCallerClients CallerClients { get; }
        #endregion
        #region "获取 中心调用方上下文对象"
        /// <summary>
        /// 获取 中心调用方上下文对象
        /// </summary>
        public HubCallerContext CallerContext { get; }
        #endregion

        #region "获取 组管理器"
        /// <summary>
        /// 获取 组管理器
        /// </summary>
        public IGroupManager Groups { get; }
        #endregion

        #region "获取或设置 连接用户"
        /// <summary>
        /// 获取或设置 连接用户
        /// </summary>
        public ConnectionUser User { get; set; }
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个集线器事件数据基类的新实例"
        /// <summary>
        /// 初始化一个集线器事件数据基类的新实例
        /// </summary>
        /// <param name="clients">调用方客户端对象</param>
        /// <param name="groups">组管理器</param>
        protected HubEventDataBase(IHubClients clients, IGroupManager groups)
        {
            Check.NotNull(clients, nameof(clients));
            Check.NotNull(groups, nameof(groups));

            Internal = false;
            Clients = clients;
            Groups = groups;

            CallerClients = null;
            CallerContext = null;
        }
        #endregion
        #region "初始化一个集线器事件数据基类的新实例"
        /// <summary>
        /// 初始化一个集线器事件数据基类的新实例
        /// </summary>
        /// <param name="callerClients">中心调用方客户端对象</param>
        /// <param name="callerContext">中心调用方上下文对象</param>
        /// <param name="groups">组管理器</param>
        protected HubEventDataBase(IHubCallerClients callerClients, HubCallerContext callerContext, IGroupManager groups)
        {
            Check.NotNull(callerClients, nameof(callerClients));
            Check.NotNull(callerContext, nameof(callerContext));
            Check.NotNull(groups, nameof(groups));

            Internal = true;
            CallerClients = callerClients;
            CallerContext = callerContext;
            Groups = groups;

            Clients = null;
        }
        #endregion

        #endregion

        #region "方法"
        #region "获取客户端对象"
        /// <summary>
        /// 获取客户端对象
        /// </summary>
        /// <param name="connectionId">连接Id</param>
        /// <returns>客户端对象</returns>
        public ISingleClientProxy GetClient(string connectionId)
        {
            ISingleClientProxy client;
            if (Internal)
            {
                client = CallerClients?.Client(connectionId);
            }
            else
            {
                client = Clients?.Client(connectionId);
            }
            return client;
        }
        #endregion
        #region "获取客户端集合对象"
        /// <summary>
        /// 获取客户端集合对象
        /// </summary>
        /// <param name="connectionIds">连接Id集合</param>
        /// <returns>客户端对象</returns>
        public IClientProxy GetClients(IEnumerable<string> connectionIds)
        {
            IClientProxy clients;
            if (Internal)
            {
                clients = CallerClients?.Clients(connectionIds);
            }
            else
            {
                clients = Clients?.Clients(connectionIds);
            }
            return clients;
        }
        #endregion

        #endregion

    }
    #endregion
    #region "强类型集线器事件数据基类"
    /// <summary>
    /// 强类型集线器事件数据基类
    /// </summary>
    public abstract class HubEventDataBase<T> : EventDataBase
        where T : class
    {
        #region "属性"
        #region "获取 中心内部调用"
        /// <summary>
        /// 获取 中心内部调用
        /// （从 类外部调用客户端方法 Hub 时，没有与调用关联的调用方。 因此，无法访问 ConnectionId 、 Caller 和 Others 属性。）
        /// </summary>
        public bool Internal { get; }
        #endregion

        #region "获取 调用方客户端对象"
        /// <summary>
        /// 获取 调用方客户端对象
        /// </summary>
        public IHubClients<T> Clients { get; }
        #endregion

        #region "获取 中心调用方客户端对象"
        /// <summary>
        /// 获取 中心调用方客户端对象
        /// </summary>
        public IHubCallerClients<T> CallerClients { get; }
        #endregion
        #region "获取 中心调用方上下文对象"
        /// <summary>
        /// 获取 中心调用方上下文对象
        /// </summary>
        public HubCallerContext CallerContext { get; }
        #endregion

        #region "获取 组管理器"
        /// <summary>
        /// 获取 组管理器
        /// </summary>
        public IGroupManager Groups { get; }
        #endregion

        #region "获取或设置 连接用户"
        /// <summary>
        /// 获取或设置 连接用户
        /// </summary>
        public ConnectionUser User { get; set; }
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个强类型集线器事件数据基类的新实例"
        /// <summary>
        /// 初始化一个强类型集线器事件数据基类的新实例
        /// </summary>
        /// <param name="clients">调用方客户端对象</param>
        /// <param name="groups">组管理器</param>
        protected HubEventDataBase(IHubClients<T> clients, IGroupManager groups)
        {
            Check.NotNull(clients, nameof(clients));
            Check.NotNull(groups, nameof(groups));

            Internal = false;
            Clients = clients;
            Groups = groups;

            CallerClients = null;
            CallerContext = null;
        }
        #endregion
        #region "初始化一个强类型集线器事件数据基类的新实例"
        /// <summary>
        /// 初始化一个强类型集线器事件数据基类的新实例
        /// </summary>
        /// <param name="callerClients">中心调用方客户端对象</param>
        /// <param name="callerContext">中心调用方上下文对象</param>
        /// <param name="groups">组管理器</param>
        protected HubEventDataBase(IHubCallerClients<T> callerClients, HubCallerContext callerContext, IGroupManager groups)
        {
            Check.NotNull(callerClients, nameof(callerClients));
            Check.NotNull(callerContext, nameof(callerContext));
            Check.NotNull(groups, nameof(groups));

            Internal = true;
            CallerClients = callerClients;
            CallerContext = callerContext;
            Groups = groups;

            Clients = null;
        }
        #endregion

        #endregion

        #region "方法"
        #region "获取客户端对象"
        /// <summary>
        /// 获取客户端对象
        /// </summary>
        /// <param name="connectionId">连接Id</param>
        /// <returns>客户端对象</returns>
        public T GetClient(string connectionId)
        {
            T client;
            if (Internal)
            {
                client = CallerClients?.Client(connectionId);
            }
            else
            {
                client = Clients?.Client(connectionId);
            }
            return client;
        }
        #endregion
        #region "获取客户端集合对象"
        /// <summary>
        /// 获取客户端集合对象
        /// </summary>
        /// <param name="connectionIds">连接Id集合</param>
        /// <returns>客户端对象</returns>
        public T GetClients(IEnumerable<string> connectionIds)
        {
            T clients;
            if (Internal)
            {
                clients = CallerClients?.Clients(connectionIds);
            }
            else
            {
                clients = Clients?.Clients(connectionIds);
            }
            return clients;
        }
        #endregion

        #endregion

    }
    #endregion
    #region "运行时解析类型集线器事件数据基类"
    /// <summary>
    /// 运行时解析类型集线器事件数据基类
    /// </summary>
    public abstract class DynamicHubEventDataBase : EventDataBase
    {
        #region "属性"
        #region "获取 中心内部调用"
        /// <summary>
        /// 获取 中心内部调用
        /// （从 类外部调用客户端方法 Hub 时，没有与调用关联的调用方。 因此，无法访问 ConnectionId 、 Caller 和 Others 属性。）
        /// </summary>
        public bool Internal { get; }
        #endregion

        #region "获取 调用方客户端对象"
        /// <summary>
        /// 获取 调用方客户端对象
        /// </summary>
        public DynamicHubClients Clients { get; }
        #endregion

        #region "获取 中心调用方客户端对象"
        /// <summary>
        /// 获取 中心调用方客户端对象
        /// </summary>
        public DynamicHubClients CallerClients { get; }
        #endregion
        #region "获取 中心调用方上下文对象"
        /// <summary>
        /// 获取 中心调用方上下文对象
        /// </summary>
        public HubCallerContext CallerContext { get; }
        #endregion

        #region "获取 组管理器"
        /// <summary>
        /// 获取 组管理器
        /// </summary>
        public IGroupManager Groups { get; }
        #endregion

        #region "获取或设置 连接用户"
        /// <summary>
        /// 获取或设置 连接用户
        /// </summary>
        public ConnectionUser User { get; set; }
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个运行时解析类型集线器事件数据基类的新实例"
        /// <summary>
        /// 初始化一个运行时解析类型集线器事件数据基类的新实例
        /// </summary>
        /// <param name="clients">调用方客户端对象</param>
        /// <param name="groups">组管理器</param>
        protected DynamicHubEventDataBase(DynamicHubClients clients, IGroupManager groups)
        {
            Check.NotNull(clients, nameof(clients));
            Check.NotNull(groups, nameof(groups));

            Internal = false;
            Clients = clients;
            Groups = groups;

            CallerClients = null;
            CallerContext = null;
        }
        #endregion
        #region "初始化一个运行时解析类型集线器事件数据基类的新实例"
        /// <summary>
        /// 初始化一个运行时解析类型集线器事件数据基类的新实例
        /// </summary>
        /// <param name="callerClients">中心调用方客户端对象</param>
        /// <param name="callerContext">中心调用方上下文对象</param>
        /// <param name="groups">组管理器</param>
        protected DynamicHubEventDataBase(DynamicHubClients callerClients, HubCallerContext callerContext, IGroupManager groups)
        {
            Check.NotNull(callerClients, nameof(callerClients));
            Check.NotNull(callerContext, nameof(callerContext));
            Check.NotNull(groups, nameof(groups));

            Internal = true;
            CallerClients = callerClients;
            CallerContext = callerContext;
            Groups = groups;

            Clients = null;
        }
        #endregion

        #endregion

        #region "方法"
        #region "获取客户端对象"
        /// <summary>
        /// 获取客户端对象
        /// </summary>
        /// <param name="connectionId">连接Id</param>
        /// <returns>客户端对象</returns>
        public dynamic GetClient(string connectionId)
        {
            dynamic client;
            if (Internal)
            {
                client = CallerClients?.Client(connectionId);
            }
            else
            {
                client = Clients?.Client(connectionId);
            }
            return client;
        }
        #endregion
        #region "获取客户端集合对象"
        /// <summary>
        /// 获取客户端集合对象
        /// </summary>
        /// <param name="connectionIds">连接Id集合</param>
        /// <returns>客户端对象</returns>
        public dynamic GetClients(IEnumerable<string> connectionIds)
        {
            dynamic clients;
            if (Internal)
            {
                clients = CallerClients?.Clients(connectionIds.ToList().AsReadOnly());
            }
            else
            {
                clients = Clients?.Clients(connectionIds.ToList().AsReadOnly());
            }
            return clients;
        }
        #endregion

        #endregion

    }
    #endregion

}
